package com.yystar.support.filter;

import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.yystar.support.servlet.HeaderCacheServletResponse;
import com.yystar.support.util.CacheUtility;
import com.yystar.support.util.SystemProperties;
import com.yystar.support.util.WTextUtility;

/**
 * 处理静态文件缓存的过滤器
 * 
 * @author liuzhifei
 * 
 */
public class CacheFilter implements Filter {

	private ServletContext _servletContext;

	// URL验证的正则
	private Pattern _urlRegexIgnorePattern;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

		_servletContext = filterConfig.getServletContext();

		String urlRegexIgnorePattern = filterConfig.getInitParameter("url-regex-ignore-pattern");

		if (WTextUtility.isNotNull(urlRegexIgnorePattern)) {
			_urlRegexIgnorePattern = Pattern.compile(urlRegexIgnorePattern);
		}
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;

		HeaderCacheServletResponse headerCacheServletResponse = new HeaderCacheServletResponse(response);

		headerCacheServletResponse.setHeader("P3P", "CP=CAO PSA OUR");

		// 当前项目不是开发模式 并且 符合需要缓存的URL请求
		if (!WTextUtility.parseBooleanString(SystemProperties.get("is.development.model")) && isMatchURLRegexPattern(request)) {

			// 获取浏览器最后的缓存时间
			long ifModifiedSince = request.getDateHeader("If-Modified-Since");

			long lastModified = System.currentTimeMillis();

			String uri = request.getRequestURI();

			CacheResponseData data = CacheUtility.getCacheData(uri);

			// 如果存在缓存
			if (data != null) {

				if (ifModifiedSince > 0) {

					// 数据的最后缓存时间
					long modelLastModifiedDate = data.getLastModified();

					// 如果数据最后缓存的时间 小于或等于 浏览器缓存的时间 则返回状态码 304 通知浏览器继续使用缓存
					if (modelLastModifiedDate <= ifModifiedSince) {

						// 解决 ie9 SEC7113: CSS 因 Mime 类型不匹配而被忽略 bug
						if (data.getContentType() != null) {
							headerCacheServletResponse.setContentType(data.getContentType());
						}
						headerCacheServletResponse.setDateHeader("Last-Modified", ifModifiedSince);
						headerCacheServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
						return;
					}
				}
			} else {

				// 添加到缓存
				addFileCache(request);
			}

			long adddaysM = 315360000;

			// 设置缓存头
			headerCacheServletResponse.setHeader("Cache-Control", "max-age=" + adddaysM + ", public");
			headerCacheServletResponse.setDateHeader("Expires", lastModified + adddaysM);
			headerCacheServletResponse.setDateHeader("Last-Modified", lastModified);
		} else {

			// 设置不缓存头
			headerCacheServletResponse.setHeader("Cache-Control", "max-age=0"); // HTTP
																				// 1.1
			headerCacheServletResponse.setHeader("Pragma", "no-cache"); // HTTP
																		// 1.0
			// headerCacheServletResponse.setDateHeader("Expires", 0);
			// //prevents caching at the proxy server
		}

		chain.doFilter(request, headerCacheServletResponse);
	}

	/**
	 * 将当前请求的静态文件加入到缓存
	 * 
	 * @param request
	 */
	protected void addFileCache(HttpServletRequest request) {

		String requestPath = request.getRequestURI();

		String contextPath = request.getContextPath();

		if (!contextPath.equals("/")) {
			requestPath = requestPath.substring(contextPath.length());
		}

		// 获取文件的完整目录
		String realPath = _servletContext.getRealPath(requestPath);

		if (realPath == null) {
			return;
		}

		realPath = realPath.replace('\\', '/');

		File file = new File(realPath);

		if (!file.exists()) {
			return;
		}

		CacheResponseData data = new CacheResponseData();
		data.setLastModified(file.lastModified());// 获取文件的最后修改时间

		// 加入到缓存中
		CacheUtility.putCacheData(request.getRequestURI(), data);
	}

	/**
	 * 验证是否符合需要缓存的静态文件URL
	 * 
	 * @param request
	 * @return
	 */
	protected boolean isMatchURLRegexPattern(HttpServletRequest request) {

		boolean matchURLRegexPattern = false;

		if (_urlRegexIgnorePattern != null) {
			Matcher matcher = _urlRegexIgnorePattern.matcher(request.getRequestURI());
			matchURLRegexPattern = matcher.find();
		}

		return matchURLRegexPattern;

	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}
}
